#include <iostream>

using std::cout;
using std::endl;

//当基类定义了虚函数的时候，就会在基类对象的存储布局的前面多一个
//虚函数指针，该虚函数指针会指向虚函数表，虚函数表简称为虚表，虚表
//中存放的是虚函数的入口地址。当派生类继承基类的时候，会吸收基类的
//虚函数，那么在派生类的对象的存储布局的前面，多一个虚函数指针，该
//虚函数指针指向派生类自己的虚函数表，也就是虚表，该虚表里面存放的
//是从基类吸收的虚函数的入口地址，当派生类对该虚函数进行重写，
//重定义之后，就会用派生类自己的虚函数的入口地址进行覆盖，存放的
//就是派生类自己的虚函数的入口地址
class Base
{
public:
    Base(long base = 0)
    : _base(base)
    {
        cout << "Base(long = 0)" << endl;
    }

    virtual 
    void print()
    {
        cout << "Base::_base = " << _base << endl;
    }


    ~Base()
    {
        cout << "~Base()" << endl;
    }
private:
    long _base;
};

class Derived
: public Base
{
public:
    Derived(long base = 0, long derived = 0)
    : Base(base)
    , _derived(derived)
    {
        cout << "Base(long = 0, long = 0)" << endl;
    }
    /* virtual */ 
    /* void print(); */
    void print()
    {
        cout << "Derived::_derived = " << _derived << endl;
    }

    ~Derived()
    {
        cout << "~Derived()" << endl;
    }
private:
    long _derived;

};

void func(Base &ref)
{
    ref.print();//同一种指令
}

int main(int argc, char **argv)
{
    //有虚函数就会多8个字节的指针
    cout << "sizeof(Base) = " << sizeof(Base) << endl;//8 16
    cout << "sizeof(Derived) = " << sizeof(Derived) << endl;//16 24

    cout << endl;
    Base base(1111);
    base.print();

    cout << endl;
    Derived derived(2222, 3333);
    derived.print();

    cout << endl;
    base.print();//将虚函数直接以普通函数的形式进行了调用,在编译的
    derived.print();//时候就已经确定了，不满足动态多态被激活的5条件

    return 0;
}

